package com.kapcb.mybatis.plus;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.reflect.GenericTypeUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.Db;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;

@SuppressWarnings("unchecked")
public interface BaseMapperPlus<T, V> extends BaseMapper<T> {

    /**
     * 获取当前实例对象关联的泛型类型 V 的 Class 对象
     *
     * @return 返回当前实例对象关联的泛型类型 V 的 Class 对象
     */
    default Class<V> currentVoClass() {
        return (Class<V>) GenericTypeUtils.resolveTypeArguments(this.getClass(), BaseMapperPlus.class)[1];
    }

    /**
     * 获取当前实例对象关联的泛型类型 T 的 Class 对象
     *
     * @return 返回当前实例对象关联的泛型类型 T 的 Class 对象
     */
    default Class<T> currentModelClass() {
        return (Class<T>) GenericTypeUtils.resolveTypeArguments(this.getClass(), BaseMapperPlus.class)[0];
    }

    /**
     * 使用默认的查询条件查询并返回结果列表
     *
     * @return 返回查询结果的列表
     */
    default List<T> selectList() {
        return this.selectList(new QueryWrapper<>());
    }

    /**
     * 批量插入实体对象集合
     *
     * @param entityList 实体对象集合
     * @return 插入操作是否成功的布尔值
     */
    default boolean insertBatch(Collection<T> entityList) {
        return Db.saveBatch(entityList);
    }

    /**
     * 批量根据 ID 更新实体对象集合
     *
     * @param entityList 实体对象集合
     * @return 更新操作是否成功的布尔值
     */
    default boolean updateBatchById(Collection<T> entityList) {
        return Db.updateBatchById(entityList);
    }

    /**
     * 批量插入或更新实体对象集合
     *
     * @param entityList 实体对象集合
     * @return 插入或更新操作是否成功的布尔值
     */
    default boolean insertOrUpdateBatch(Collection<T> entityList) {
        return Db.saveOrUpdateBatch(entityList);
    }

    /**
     * 批量插入实体对象集合并指定批处理大小
     *
     * @param entityList 实体对象集合
     * @param batchSize  批处理大小
     * @return 插入操作是否成功的布尔值
     */
    default boolean insertBatch(Collection<T> entityList, int batchSize) {
        return Db.saveBatch(entityList, batchSize);
    }

    /**
     * 批量根据 ID 更新实体对象集合并指定批处理大小
     *
     * @param entityList 实体对象集合
     * @param batchSize  批处理大小
     * @return 更新操作是否成功的布尔值
     */
    default boolean updateBatchById(Collection<T> entityList, int batchSize) {
        return Db.updateBatchById(entityList, batchSize);
    }

    /**
     * 批量插入或更新实体对象集合并指定批处理大小
     *
     * @param entityList 实体对象集合
     * @param batchSize  批处理大小
     * @return 插入或更新操作是否成功的布尔值
     */
    default boolean insertOrUpdateBatch(Collection<T> entityList, int batchSize) {
        return Db.saveOrUpdateBatch(entityList, batchSize);
    }

    /**
     * 根据条件查询单个 VO 对象
     *
     * @param wrapper 查询条件 Wrapper
     * @return 查询到的单个 VO 对象
     */
    // default V selectVoOne(Wrapper<T> wrapper) {
    //     return selectVoOne(wrapper, this.currentVoClass());
    // }

    // /**
    //  * 根据条件查询单个 VO 对象，并根据需要决定是否抛出异常
    //  *
    //  * @param wrapper 查询条件 Wrapper
    //  * @param throwEx 是否抛出异常的标志
    //  * @return 查询到的单个 VO 对象
    //  */
    // default V selectVoOne(Wrapper<T> wrapper, boolean throwEx) {
    //     return selectVoOne(wrapper, this.currentVoClass(), throwEx);
    // }
    //
    // /**
    //  * 根据条件查询单个 VO 对象，并指定返回的 VO 对象的类型
    //  *
    //  * @param wrapper 查询条件 Wrapper
    //  * @param voClass 返回的 VO 对象的 Class 对象
    //  * @param <C>     返回的 VO 对象的类型
    //  * @return 查询到的单个 VO 对象，经过类型转换为指定的 VO 类后返回
    //  */
    // default <C> C selectVoOne(Wrapper<T> wrapper, Class<C> voClass) {
    //     return selectVoOne(wrapper, voClass, true);
    // }

    // /**
    //  * 查询所有 VO 对象列表
    //  *
    //  * @return 查询到的 VO 对象列表
    //  */
    // default List<V> selectVoList() {
    //     return selectVoList(new QueryWrapper<>(), this.currentVoClass());
    // }

    // /**
    //  * 根据条件查询VO对象列表
    //  *
    //  * @param wrapper 查询条件 Wrapper
    //  * @return 查询到的 VO 对象列表
    //  */
    // default List<V> selectVoList(Wrapper<T> wrapper) {
    //     return selectVoList(wrapper, this.currentVoClass());
    // }

    // /**
    //  * 根据条件分页查询 O 对象列表
    //  *
    //  * @param page    分页信息
    //  * @param wrapper 查询条件 Wrapper
    //  * @return 查询到的 VO 对象分页列表
    //  */
    // default <P extends IPage<V>> P selectVoPage(IPage<T> page, Wrapper<T> wrapper) {
    //     return selectVoPage(page, wrapper, this.currentVoClass());
    // }

}
